﻿// ## 2023/06/26 #江东新风# 将AI对应功能合并入该文件 ##
// ## 2020/08/07 # 氕氘氚 # 规则、代碼优化 ##
/*
@제작자: HoneyBee
@설명: 통솔, 지력이 동시에 높은 무장이 [군주, 도독] 신분이거나 [평북장군] 이상의 관직인 경우에 활용할 수 있는 부대 메뉴


※ COMMANDER TYPE 부대의 효과

(1) 부대 주위 아군 기력 회복
(2) 부대 주위 적군 기력 감소
(3) 부대 주위 아군 병력 회복
(4) 부대 주위 적군 병력 흡수 (심공 효과)


*/

namespace 部队指令_部队战略
{

	// ================ CUSTOMIZE ================


	const bool 开启部队战略_玩家 = true; 			// 부대전략메뉴_사용 설정 (true = on / false = off)

	const bool 战略_士气高涨_사용 = true; 			// 战略_士气高涨_사용 설정 (true = on / false = off)
	const bool 战略_动摇敌军_사용 = true; 			// 战略_动摇敌军_사용 설정 (true = on / false = off)
	const bool 战略_援军支援_사용 = true; 			// 战略_援军支援_사용 설정 (true = on / false = off)
	const bool 战略_煽动敌军_사용 = true; 			// 战略_煽动敌军_사용 설정 (true = on / false = off)

	const int ENERGY_COST_战略_士气高涨 = 40;     // 战略_士气高涨 기력 필요량
	const int ENERGY_COST_战略_动摇敌军 = 40;     // 战略_动摇敌军 기력 필요량
	const int ENERGY_COST_战略_援军支援 = 40;     // 战略_援军支援 기력 필요량
	const int ENERGY_COST_战略_煽动敌军 = 40;     // 战略_煽动敌军 기력 필요량

	const int 兵力条件 = 5000;
	const int 统率条件 = 80;
	const int 智力条件 = 80;

	// =============== AICUSTOMIZE ===============
	// 이미 부대전략메뉴가 존재하므로 효과는 AI만으로 설정하는 것을 권장
	const bool 仅AI有效 = true;  			// true =AI만 효과적용, false =유저와 AI 모두 효과 적용 

	const int 发动时机 = 0;        	   	   		// 0: 매턴,  1: 매월 1일,  2: 매분기 첫달1일

	const int 发动机率 = 10;      			// 효과가 발휘되는 확률 (기본 10%)

	const int 气力条件 = 80;

	const int 관직조건 = 관직_평북장군;			// 평북장군 이상의 관직

	// ===========================================


	class Main
	{
		pk::unit@ src_unit;
		pk::point src_pos_;
		pk::person@ src_leader;
		pk::building@ src_building;

		Main()
		{
			// 부대 메뉴 추가
			add_menu_unit_order();
			//AI战略相关
			pk::bind(107, pk::trigger107_t(callback));
		}
		
		/////////////////////////////////////////////////////////////////////////////AI功能相关/////////////////////////////////////////////////////////////////////////////////////////

		void callback()
		{
			//未开启开关，则ai不执行策略
			if (!ch::get_set_p(0).get_mod_set(战术战略妙计_开关))
				return;
			// 발동시기 매턴
			if (发动时机 == 0)
			{
				effect_战略();
			}
			// 매월 1일
			else if (发动时机 == 1 and (pk::get_day() == 1))
			{
				effect_战略();
			}
			// 매분기 첫달이면서 1일	
			else if (发动时机 == 2 and (pk::get_day() == 1) and pk::is_first_month_of_quarter(pk::get_month()))
			{
				effect_战略();
			}

		}

		// 유저 또는 AI만 적용 시 판단함수
		bool only_AI_unit(pk::unit@ unit)
		{
			if (仅AI有效 and unit.is_player()) return false;
			return true;
		}

		// 신분이 [군주/도독]이거나 관직이 [평북장군]이상인 부대의 무장이 통솔 80대 + 지력 80대
		void effect_战略()
		{
			auto list = pk::list_to_array(pk::get_unit_list());

			for (int i = 0; i < int(list.length); i++)
			{
				if (!pk::rand_bool(发动机率)) 	continue;

				pk::unit@ src = list[i];
				pk::person@ src_leader = pk::get_person(src.leader);
				pk::point pos = src.get_pos();

				int n = pk::rand(4);

				if (only_AI_unit(src) && src.energy > 气力条件)
				{

					if ((src.leader == pk::get_kunshu_id(src)) or (src.leader == pk::get_totoku_id(src)) or (src_leader.rank <= 관직조건))
					{

						// 부대 주위 아군 기력 회복
						if (n == 0)
						{
							global_func_士气高漲(pos, @src, @src_leader);

						} // 부대 주위 아군 기력 회복


						// 부대 주위 적군 기력 감소
						if (n == 1)
						{
							global_func_敌军动摇(pos, @src, @src_leader);

						} // 부대 주위 적군 기력 감소


						// 부대 주위 아군 병력 회복 
						if (n == 2)
						{
							global_func_援军支援(pos, @src, @src_leader);

						} // 부대 주위 아군 병력 회복 


						// 부대 주위 적군 병력 흡수 (심공 효과)
						if (n == 3)
						{
							global_func_敌军煽动(pos, @src, @src_leader);

						} // 부대 주위 적군 병력 감소 (심공 효과)  

					} // if (신분 조건)

				} // (only_AI_unit(src))

			} // for 

		} // effect_战略


		////////////////////////////////////////////////////////////////////////////菜单功能相关////////////////////////////////////////////////////////////////////////////////////////

		void add_menu_unit_order()
		{
			if (开启部队战略_玩家)
			{
				pk::menu_item 部队;
				int 部队_上位菜单;

				部队.menu = 1;
				部队.get_text = cast<pk::menu_item_get_text_t@>(function() { return pk::encode("部队战略"); });
				部队.init = cast<pk::unit_menu_item_init_t@>(function(unit, src_pos) { @main.src_unit = @unit; main.src_pos_ = src_pos; });
				部队.is_visible = cast<pk::menu_item_is_visible_t@>(function() { if (!ch::get_set_p(0).get_mod_set(战术战略妙计_开关)) return false; else return (main.src_unit).type == 部队类型_战斗; });
				部队_上位菜单 = pk::add_menu_item(部队);

				// 부대전략메뉴 : 주위 아군 기력 회복
				if (战略_士气高涨_사용)
				{
					pk::menu_item 战略_士气高涨;
					战略_士气高涨.menu = 部队_上位菜单;
					战略_士气高涨.init = pk::unit_menu_item_init_t(init);
					战略_士气高涨.get_text = pk::menu_item_get_text_t(getText_战略_士气高涨);
					战略_士气高涨.get_desc = pk::menu_item_get_desc_t(getDesc_战略_士气高涨);
					战略_士气高涨.is_visible = pk::menu_item_is_visible_t(isVisible);
					战略_士气高涨.is_enabled = pk::menu_item_is_enabled_t(isEnabled_战略_士气高涨);
					战略_士气高涨.handler = pk::unit_menu_item_handler_t(handler_战略_士气高涨);
					pk::add_menu_item(战略_士气高涨);
				}

				// 부대전략메뉴 : 주위 적군 기력 감소
				if (战略_动摇敌军_사용)
				{
					pk::menu_item 战略_动摇敌军;
					战略_动摇敌军.menu = 部队_上位菜单;
					战略_动摇敌军.init = pk::unit_menu_item_init_t(init);
					战略_动摇敌军.get_text = pk::menu_item_get_text_t(getText_战略_动摇敌军);
					战略_动摇敌军.get_desc = pk::menu_item_get_desc_t(getDesc_战略_动摇敌军);
					战略_动摇敌军.is_visible = pk::menu_item_is_visible_t(isVisible);
					战略_动摇敌军.is_enabled = pk::menu_item_is_enabled_t(isEnabled_战略_动摇敌军);
					战略_动摇敌军.handler = pk::unit_menu_item_handler_t(handler_战略_动摇敌军);
					pk::add_menu_item(战略_动摇敌军);
				}

				// 부대전략메뉴 : 주위 아군 병력 회복
				if (战略_援军支援_사용)
				{
					pk::menu_item 战略_援军支援;
					战略_援军支援.menu = 部队_上位菜单;
					战略_援军支援.init = pk::unit_menu_item_init_t(init);
					战略_援军支援.get_text = pk::menu_item_get_text_t(getText_战略_援军支援);
					战略_援军支援.get_desc = pk::menu_item_get_desc_t(getDesc_战略_援军支援);
					战略_援军支援.is_visible = pk::menu_item_is_visible_t(isVisible);
					战略_援军支援.is_enabled = pk::menu_item_is_enabled_t(isEnabled_战略_援军支援);
					战略_援军支援.handler = pk::unit_menu_item_handler_t(handler_战略_援军支援);
					pk::add_menu_item(战略_援军支援);
				}

				// 부대전략메뉴 : 주위 적군 병력 흡수
				if (战略_煽动敌军_사용)
				{
					pk::menu_item 战略_煽动敌军;
					战略_煽动敌军.menu = 部队_上位菜单;
					战略_煽动敌军.init = pk::unit_menu_item_init_t(init);
					战略_煽动敌军.get_text = pk::menu_item_get_text_t(getText_战略_煽动敌军);
					战略_煽动敌军.get_desc = pk::menu_item_get_desc_t(getDesc_战略_煽动敌军);
					战略_煽动敌军.is_visible = pk::menu_item_is_visible_t(isVisible);
					战略_煽动敌军.is_enabled = pk::menu_item_is_enabled_t(isEnabled_战略_煽动敌军);
					战略_煽动敌军.handler = pk::unit_menu_item_handler_t(handler_战略_煽动敌军);
					pk::add_menu_item(战略_煽动敌军);
				}

			}

		} // add_menu_unit_order

		void init(pk::unit@ unit, pk::point src_pos)
		{
			@src_unit = @unit;
			src_pos_ = src_pos;
			@src_leader = pk::get_person(src_unit.leader);
			@src_building = pk::get_building(src_leader.service);
		}

		bool isVisible()
		{
			if (pk::is_campaign()) return false;
			if (!ch::get_set_p(0).get_mod_set(战术战略妙计_开关)) return false;
			return true;
		}

		//---------------------------------------------------------------------------
		// 부대전략메뉴 : 战略_士气高涨 
		//---------------------------------------------------------------------------

		string getText_战略_士气高涨()
		{
			return pk::encode(pk::format("士气高涨 ({})", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_士气高涨)));
		}

		string getDesc_战略_士气高涨()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_士气高涨))
				return pk::encode("气力不足.");
			else if (src_unit.troops < 兵力条件)
				return pk::encode("兵力不足.");
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군))
				return pk::encode("身分/官职不符合条件.");
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件))
				return pk::encode("统率/智力不符合条件.");
			else
				return pk::encode(pk::format("使用士气高涨.(气力至少 {} 以上)", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_士气高涨)));
		}

		bool isVisible_战略_士气高涨()
		{
			return true;
		}

		bool isEnabled_战略_士气高涨()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_士气高涨)) return false;
			else if (src_unit.troops < 兵力条件) return false;
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군)) return false;
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件)) return false;
			return true;
		}

		bool handler_战略_士气高涨(pk::point dst_pos)
		{

			global_func_士气高漲(src_pos_, @src_unit, @src_leader);

			// 실행 부대 기력 감소
			pk::add_energy(src_unit, -global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_士气高涨), true);

			// 행동완료
			src_unit.action_done = true;
			if (int(pk::option["San11Option.EnableInfiniteAction"]) != 0)
				src_unit.action_done = false;

			return true;
		}


		//---------------------------------------------------------------------------
		// 부대전략메뉴 : 战略_动摇敌军
		//---------------------------------------------------------------------------

		string getText_战略_动摇敌军()
		{
			return pk::encode(pk::format("动摇敌军 ({})", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_动摇敌军)));
		}

		string getDesc_战略_动摇敌军()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_动摇敌军))
				return pk::encode("气力不足.");
			else if (src_unit.troops < 兵力条件)
				return pk::encode("兵力不足.");
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군))
				return pk::encode("身分/官职不符合条件.");
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件))
				return pk::encode("统率/智力不符合条件");
			else
				return pk::encode(pk::format("使用动摇敌军.(气力至少 {} 以上)", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_动摇敌军)));
		}

		bool isVisible_战略_动摇敌军()
		{
			return true;
		}

		bool isEnabled_战略_动摇敌军()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_动摇敌军)) return false;
			else if (src_unit.troops < 兵力条件) return false;
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군)) return false;
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件)) return false;
			return true;
		}

		bool handler_战略_动摇敌军(pk::point dst_pos)
		{

			global_func_敌军动摇(src_pos_, @src_unit, @src_leader);

			// 실행 부대 기력 감소
			pk::add_energy(src_unit, -global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_动摇敌军), true);

			// 행동완료
			src_unit.action_done = true;
			if (int(pk::option["San11Option.EnableInfiniteAction"]) != 0)
				src_unit.action_done = false;

			return true;
		}


		//---------------------------------------------------------------------------
		// 부대전략메뉴 : 战略_援军支援 
		//---------------------------------------------------------------------------

		string getText_战略_援军支援()
		{
			return pk::encode(pk::format("援军支援 ({})", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_援军支援)));
		}

		string getDesc_战略_援军支援()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_援军支援))
				return pk::encode("气力不足.");
			else if (src_unit.troops < 兵力条件)
				return pk::encode("兵力不足.");
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군))
				return pk::encode("身分/官职不符合条件.");
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件))
				return pk::encode("统率/智力不符合条件.");
			else if ((pk::get_troops(src_building) < 援军支援加兵 * 10 or pk::get_food(src_building) < 援军支援加粮 * 20))
				return pk::encode("据点兵力/军粮不足");
			else
				return pk::encode(pk::format("使用援军支援.(气力至少 {} 以上)", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_援军支援)));
		}

		bool isVisible_战略_援军支援()
		{
			return true;
		}

		bool isEnabled_战略_援军支援()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_援军支援)) return false;
			else if (src_unit.troops < 兵力条件) return false;
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군)) return false;
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件)) return false;
			else if ((pk::get_troops(src_building) < 援军支援加兵 * 10 or pk::get_food(src_building) < 援军支援加粮 * 20)) return false;
			return true;
		}

		bool handler_战略_援军支援(pk::point dst_pos)
		{
			global_func_援军支援(src_pos_, @src_unit, @src_leader);

			// 실행 부대 기력 감소
			pk::add_energy(src_unit, -global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_援军支援), true);

			// 행동완료
			src_unit.action_done = true;
			if (int(pk::option["San11Option.EnableInfiniteAction"]) != 0)
				src_unit.action_done = false;

			return true;
		}


		//---------------------------------------------------------------------------
		// 부대전략메뉴 : 战略_煽动敌军 
		//---------------------------------------------------------------------------

		string getText_战略_煽动敌军()
		{
			return pk::encode(pk::format("煽动敌军 ({})", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_煽动敌军)));
		}

		string getDesc_战略_煽动敌军()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_煽动敌军))
				return pk::encode("气力不足.");
			else if (src_unit.troops < 兵力条件)
				return pk::encode("兵力不足.");
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군))
				return pk::encode("身分/官职不符合条件.");
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件))
				return pk::encode("统率/智力不符合条件.");
			else
				return pk::encode(pk::format("使用煽动敌军.(气力至少 {} 以上)", global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_煽动敌军)));
		}

		bool isVisible_战略_煽动敌军()
		{
			return true;
		}

		bool isEnabled_战略_煽动敌军()
		{
			if (src_unit.energy < global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_煽动敌军)) return false;
			else if (src_unit.troops < 兵力条件) return false;
			else if ((src_unit.leader != pk::get_kunshu_id(src_unit)) and (src_unit.leader != pk::get_totoku_id(src_unit)) and (src_leader.rank > 관직_평북장군)) return false;
			else if ((src_leader.stat[武将能力_统率] < 统率条件) or (src_leader.stat[武将能力_智力] < 智力条件)) return false;
			return true;
		}

		bool handler_战略_煽动敌军(pk::point dst_pos)
		{
			global_func_敌军煽动(src_pos_, @src_unit, @src_leader);

			// 실행 부대 기력 감소
			pk::add_energy(src_unit, -global_func_最终气力消耗(@src_unit, ENERGY_COST_战略_煽动敌军), true);

			// 행동완료
			src_unit.action_done = true;
			if (int(pk::option["San11Option.EnableInfiniteAction"]) != 0)
				src_unit.action_done = false;

			return true;
		}


	} // class Main

	Main main;

} // namespace